package com.fangzhi.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fangzhi.mobel.*;
import com.fangzhi.mobel.enums.GlobalCodeEnum;
import com.fangzhi.mobel.io.*;
import com.fangzhi.mobel.vo.*;
import com.fangzhi.service.*;
import com.fangzhi.utils.GlobalParam;
import com.fangzhi.utils.ResponseResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private OrdersService ordersService;
    @Autowired
    private OrderPaymentService orderPaymentService;
    @Autowired
    private OrderProductsService orderProductsService;
    @Autowired
    private RoleBaseInfoService roleBaseInfoService;
    @Autowired
    private DeptBaseInfoService deptBaseInfoService;
    @Autowired
    private AdminAccountInfoService adminAccountInfoService;
    @Autowired
    private AdminAccountRoleDeptRelationService adminAccountRoleDeptRelationService;
    @Autowired
    private OrderLogisticsService orderLogisticsService;
    @Autowired
    private ProductTypeService productTypeService;
    @PostMapping("/saveOrder")
    @Transactional
    public ResponseResult saveOrder(@RequestBody SaveOrderIo io){
        try {
            if (null != io.getImageComments())
                io.setImageComments(io.getImageComments().replace(GlobalParam.IMAGE_URL, ""));
            if (null !=  io.getPaymenyIo())
                io.getPaymenyIo().setImageCover(io.getPaymenyIo().getImageCover().replace(GlobalParam.IMAGE_URL, ""));
            Orders orders;
            if (StringUtils.hasText(io.getOrderId())){
                // 验证商品信息是否都存在
                StringBuilder  sb = new StringBuilder();
                for (SaveOrderIo.Product product : io.getProductList()) {
                    ProductType one = productTypeService.getOne(Wrappers.<ProductType>lambdaQuery()
                            .eq(ProductType::getId, product.getProductTypeId())
                            .eq(ProductType::getProductName, product.getProductName()));
                    if (null == one)
                        sb.append(product.getProductName()).append("<br/>");
                }
                if (StringUtils.hasText(sb)){
                    sb.append("以上商品不存在，请删除后重新，重新添加");
                    return ResponseResult.fail(100002, sb);
                }


                // 重新提交订单
                orders = ordersService.updateOrder(io.getOrderId(), io);
                // 清空 order_product, order_payment
                orderProductsService.remove(Wrappers.<OrderProducts>lambdaQuery().eq(OrderProducts::getOrderId, io.getOrderId()));
                orderPaymentService.remove(Wrappers.<OrderPayment>lambdaQuery().eq(OrderPayment::getOrderId, io.getOrderId()));
            }else {
                orders = ordersService.saveOrder(io);
            }
            Integer productPrice = orderProductsService.saveOrderDetail(orders.getOrderId(), io.getProductList());
            Integer paymentPrice = orderPaymentService.saveByOrderId(orders.getOrderId(), io.getPaymenyIo());
            if (null != productPrice && null != paymentPrice){
                BigDecimal discountAmount = io.getDiscountAmount().multiply(BigDecimal.valueOf(100));
                boolean b = ordersService.updateById(orders.setTotalAmount(productPrice)
                        .setDepositAmount(paymentPrice).setDiscountAmount(discountAmount.intValue()));
                if (b)
                    return ResponseResult.OK();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        throw new RuntimeException("新增订单异常" + JSON.toJSONString(io));
    }

    /**
     * 删除订单
     * @param orderId
     * @return
     */
    @GetMapping("/removeOrder")
    public ResponseResult removeOrder(@RequestParam String orderId){
        LoginVo loginVo = GlobalParam.LOGIN_ACCOUNT_INFO.get();
        AdminAccountRoleDeptRelation one = adminAccountRoleDeptRelationService.getOne(Wrappers.<AdminAccountRoleDeptRelation>lambdaQuery()
                .eq(AdminAccountRoleDeptRelation::getAdminAccounntId, loginVo.getId()));
        if (one.getRoleId() != 6L)
            return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9997);

        ordersService.remove(Wrappers.<Orders>lambdaQuery().eq(Orders::getOrderId, orderId));
        orderProductsService.remove(Wrappers.<OrderProducts>lambdaQuery().eq(OrderProducts::getOrderId, orderId));
        orderPaymentService.remove(Wrappers.<OrderPayment>lambdaQuery().eq(OrderPayment::getOrderId, orderId));
        orderReceiptService.remove(Wrappers.<OrderReceipt>lambdaQuery().eq(OrderReceipt::getOrderId, orderId));
        orderLogisticsService.remove(Wrappers.<OrderLogistics>lambdaQuery().eq(OrderLogistics::getOrderId, orderId));
        orderAfterService.remove(Wrappers.<OrderAfter>lambdaQuery().eq(OrderAfter::getOrderId, orderId));
        return ResponseResult.OK();
    }

    /**
     * 订单列表
     * @param roleId
     * @param deptId
     * @param accountId
     * @param orderType 0:所有订单 1：售后订单
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping("/orderList")
    public ResponseResult orderList(@RequestParam(defaultValue = "0") Integer roleId
                                , @RequestParam String deptId
                                , @RequestParam(defaultValue = "") String orderId
                                , @RequestParam(defaultValue = "") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate beginTime
                                , @RequestParam(defaultValue = "") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endTime
                                , @RequestParam(defaultValue = "0", name = "userId") Integer accountId
                                , @RequestParam(defaultValue = "", name = "name") String name
                                , @RequestParam(defaultValue = "0", name = "orderType") Integer orderType
                                , @RequestParam(defaultValue = "0", name = "receiptType") Integer receiptType
                                , @RequestParam(defaultValue = "0", name = "orderLogisticsType") Integer orderLogisticsType
                                , @RequestParam(defaultValue = "", name = "logisticsStr") String logisticsStr
                                , @RequestParam(defaultValue = "1") Integer pageNo
                                , @RequestParam(defaultValue = "20") Integer pageSize){
        List<RoleListVo> roleListVos = roleBaseInfoService.roleList(roleId);
        List<DeptListVo> deptListVos = deptBaseInfoService.deptList(deptId);
        if (roleListVos.isEmpty() || deptListVos.isEmpty())
            return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9997);


        LoginVo loginVo = GlobalParam.LOGIN_ACCOUNT_INFO.get();
        if (loginVo.getRoleId() == 3)
            accountId = loginVo.getId().intValue();

        List<Long> roleIds = roleListVos.stream().map(T -> T.getId()).collect(Collectors.toList());
        List<Long> deptIds = deptListVos.stream().map(T -> T.getId()).collect(Collectors.toList());
        List<Long> accountIds = adminAccountInfoService.accountList(roleIds, deptIds, accountId);
        if (accountIds.isEmpty())
            return ResponseResult.OK(new ArrayList<>());
        return ordersService.orderList(logisticsStr, orderId.trim(), name.trim(), orderType, beginTime, endTime, accountIds, receiptType, orderLogisticsType, pageNo, pageSize);
    }

    @GetMapping("/orderDetail")
    public ResponseResult orderDetail(@RequestParam String orderId){
        List<RoleListVo> roleListVos = roleBaseInfoService.roleList(0);
        List<DeptListVo> deptListVos = deptBaseInfoService.deptList(0);
        if (roleListVos.isEmpty() || deptListVos.isEmpty())
            return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9997);


        List<Long> roleIds = roleListVos.stream().map(T -> T.getId()).collect(Collectors.toList());
        List<Long> deptIds = deptListVos.stream().map(T -> T.getId()).collect(Collectors.toList());
        List<Long> accountIds = adminAccountInfoService.accountList(roleIds, deptIds, 0);
        if (accountIds.isEmpty())
            return ResponseResult.OK(new ArrayList<>());
        return ordersService.orderDetail(accountIds, orderId);
    }

    @GetMapping("/unapprovedOrderList")
    public ResponseResult unapprovedOrderList(@RequestParam(defaultValue = "1") Integer pageNo
                                        , @RequestParam(defaultValue = "20") Integer pageSize){
        LoginVo loginVo = GlobalParam.LOGIN_ACCOUNT_INFO.get();
        AdminAccountRoleDeptRelation one = adminAccountRoleDeptRelationService
                .getOne(Wrappers.<AdminAccountRoleDeptRelation>lambdaQuery()
                .eq(AdminAccountRoleDeptRelation::getAdminAccounntId, loginVo.getId()));
        if (null == one)
            return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9997);

//        if (one.getRoleId() == 2){
//            // 负责人
//            List<RoleListVo> roleListVos = roleBaseInfoService.roleList(0);
//            List<DeptListVo> deptListVos = deptBaseInfoService.deptList(0);
//            if (roleListVos.isEmpty() || deptListVos.isEmpty())
//                return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9997);
//
//
//            List<Long> roleIds = roleListVos.stream().map(T -> T.getId()).collect(Collectors.toList());
//            List<Long> deptIds = deptListVos.stream().map(T -> T.getId()).collect(Collectors.toList());
//            List<Long> accountIds = adminAccountInfoService.accountList(roleIds, deptIds, 0);
//            return ordersService.unapprovedOrderList(accountIds, pageNo, pageSize);
//        }else
        if (one.getRoleId() == 4){
            // 文员
            return ordersService.unapprovedOrderListFour(pageNo, pageSize);
        }
//        else if (one.getRoleId() == 5){
//            // 财务
//            return ordersService.unapprovedOrderListFive(pageNo, pageSize);
//        }
        return ResponseResult.OK(new ArrayList<>());
    }

    /**
     * 审核
     * @param id
     * @param type  1:订单 2：回款 3：售后
     * @param  pass 1:通过 2：不通过
     * @return
     */
//    @GetMapping("/toExists")
    public ResponseResult toExists(@RequestParam Integer id, @RequestParam Integer type, @RequestParam Integer pass){
        LoginVo loginVo = GlobalParam.LOGIN_ACCOUNT_INFO.get();
        AdminAccountRoleDeptRelation one = adminAccountRoleDeptRelationService.getOne(Wrappers.<AdminAccountRoleDeptRelation>lambdaQuery()
                .eq(AdminAccountRoleDeptRelation::getAdminAccounntId, loginVo.getId()));
        if (one.getRoleId() != 2 && one.getRoleId() != 5)
            return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9997);

        Integer needStatus = 0;
        if (one.getRoleId() == 2){
            needStatus = 1;
        }else if (one.getRoleId() == 5){
            needStatus = 2;
        }
        if (type == 1){
            return ordersService.toExists(id, needStatus, pass);
        }else if (type == 2){
            return orderPaymentService.toExists(id, needStatus, one.getRoleId(), pass);
        }else if(type == 3){
           return orderAfterService.toExists(id, needStatus, one.getRoleId(), pass);
        }
        return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9999);
    }

    /**
     * 订单填写物流单号
     * @param io
     * @return
     */
    @PostMapping("/trackingLogistics")
    public ResponseResult trackingLogistics(@RequestBody TrackingLogisticsIo io){
        io.setImage(io.getImage().replace(GlobalParam.IMAGE_URL, ""));
        LoginVo loginVo = GlobalParam.LOGIN_ACCOUNT_INFO.get();
        AdminAccountRoleDeptRelation one = adminAccountRoleDeptRelationService.getOne(Wrappers.<AdminAccountRoleDeptRelation>lambdaQuery()
                .eq(AdminAccountRoleDeptRelation::getAdminAccounntId, loginVo.getId()));
        if (one.getRoleId() != 4 && one.getRoleId() != 6)
            return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9997);

        Orders byId = ordersService.getById(io.getId());
        if (null == byId || byId.getStatus() != 3)
            return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9996);

        byId.setLogisticId(io.getLogisticId()).setLogisticName(io.getLogisticName()).setStatus(4);
//        if (byId.getTotalAmount() <= (byId.getAfterAmount() + byId.getDepositAmount() + byId.getDiscountAmount()))
//            byId.setStatus(5);
        boolean b = ordersService.updateById(byId);
        if (b){
            OrderLogistics orderLogistics = new OrderLogistics().setOrderId(byId.getOrderId()).setLogisticName(io.getLogisticName())
                    .setLogisticId(io.getLogisticId()).setAccountId(loginVo.getId()).setComments(io.getComments()).setMobile(io.getMobile())
                    .setImage(io.getImage());
            orderLogisticsService.save(orderLogistics);
            return ResponseResult.OK();
        }

        return ResponseResult.systemException();
    }

    /**
     * 新增或修改订单物流
     * @return
     */
    @PostMapping("/saveOrUpdateOrderLogistics")
    public ResponseResult saveOrUpdateOrderLogistics(@RequestBody SaveOrUpdateOrderLogisticsIo io){
        io.setImage(io.getImage().replace(GlobalParam.IMAGE_URL, ""));
        LoginVo loginVo = GlobalParam.LOGIN_ACCOUNT_INFO.get();
        OrderLogistics orderLogistics = new OrderLogistics().setId(io.getId()).setOrderId(io.getOrderId())
                .setLogisticName(io.getLogisticsCompany()).setLogisticId(io.getTrackingNumber())
                .setAccountId(loginVo.getId()).setComments(io.getComments()).setMobile(io.getMobile())
                .setImage(io.getImage());
        boolean b = orderLogisticsService.saveOrUpdate(orderLogistics);
        if (b)
            return ResponseResult.OK();
        return ResponseResult.systemException();
    }

    @Autowired
    private OrderAfterService orderAfterService;

    /**
     * 新增售后订单
     * @param io
     * @return
     */
    @PostMapping("/saveAfterOrder")
    public ResponseResult saveAfterOrder(@RequestBody SaveAfterOrderIo io){
        if (null != io.getImageCover())
            io.setImageCover(io.getImageCover().replace(GlobalParam.IMAGE_URL, ""));
        return orderAfterService.saveAfterOrder(io);
    }


    @Autowired
    private OrderReceiptService orderReceiptService;



    /**
     * 订单回执列表
     * @param orderId
     * @return
     */
    @GetMapping("/receiptList")
    public ResponseResult receiptList(@RequestParam String orderId){
        LoginVo loginVo = GlobalParam.LOGIN_ACCOUNT_INFO.get();
        AdminAccountRoleDeptRelation one = adminAccountRoleDeptRelationService.getOne(Wrappers.<AdminAccountRoleDeptRelation>lambdaQuery()
                .eq(AdminAccountRoleDeptRelation::getAdminAccounntId, loginVo.getId()));
        if (one.getRoleId() != 4L && one.getRoleId() != 5L && one.getRoleId() != 6L)
            return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9997);

        List<OrderReceipt> list = orderReceiptService.list(Wrappers.<OrderReceipt>lambdaQuery().eq(OrderReceipt::getOrderId, orderId));
        List<ReceiptListVo> collect = list.parallelStream().map(T -> new ReceiptListVo()
                .setId(T.getId()).setReceiptCompany(T.getReceiptCompany())
                .setReceiptTotalAmount(T.getReceiptTotalAmount() / 100D)
                .setReceiptShippingFee(T.getReceiptShippingFee() / 100D)
                .setOrderId(T.getOrderId())
                .setImage(T.getImage())).collect(Collectors.toList());
        return ResponseResult.OK(collect);
    }

    /**
     * 删除回执订单
     * @param receiptId
     * @return
     */
    @GetMapping("removeReceipt")
    public ResponseResult removeReceipt(@RequestParam long receiptId){
        LoginVo loginVo = GlobalParam.LOGIN_ACCOUNT_INFO.get();
        AdminAccountRoleDeptRelation one = adminAccountRoleDeptRelationService.getOne(Wrappers.<AdminAccountRoleDeptRelation>lambdaQuery()
                .eq(AdminAccountRoleDeptRelation::getAdminAccounntId, loginVo.getId()));
        if (one.getRoleId() != 4L && one.getRoleId() != 5L && one.getRoleId() != 6L)
            return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9997);

        boolean delete = orderReceiptService.removeById(receiptId);
        if (delete)
            return ResponseResult.OK();
        return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9996);
    }

    /**
     * 新增订单回执单
     * @param io
     * @return
     */
    @PostMapping("/saveReceiptImage")
    public ResponseResult saveReceiptImage(@RequestBody SaveReceiptImageIo io){
        if (null != io.getImage())
            io.setImage(io.getImage().replace(GlobalParam.IMAGE_URL, ""));

        LoginVo loginVo = GlobalParam.LOGIN_ACCOUNT_INFO.get();
        AdminAccountRoleDeptRelation one = adminAccountRoleDeptRelationService.getOne(Wrappers.<AdminAccountRoleDeptRelation>lambdaQuery()
                .eq(AdminAccountRoleDeptRelation::getAdminAccounntId, loginVo.getId()));
        if (one.getRoleId() != 4L && one.getRoleId() != 5L && one.getRoleId() != 6L)
            return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9997);

        BigDecimal subtract = io.getReceiptShippingFee().multiply(BigDecimal.valueOf(100));

        BigDecimal receiptTotalAmount = io.getReceiptTotalAmount().multiply(BigDecimal.valueOf(100));
        OrderReceipt orderReceipt = new OrderReceipt().setOrderId(io.getOrderId()).setReceiptCompany(io.getReceiptCompany())
                .setImage(io.getImage())
                .setReceiptShippingFee(subtract.intValue()).setReceiptTotalAmount(receiptTotalAmount.intValue());
        if (io.getId() > 0)
            orderReceipt.setId(io.getId());
        boolean save = orderReceiptService.saveOrUpdate(orderReceipt);
        if (save)
            return ResponseResult.OK();
        return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9996);
    }

    @GetMapping("/queryOrderLogisticsDetail")
    public ResponseResult queryOrderLogisticsDetail(String orderId){
        QueryOrderLogisticsDetailVo vo = ordersService.queryOrderLogistics(orderId);
        if(null == vo)
            return ResponseResult.OK(vo);
        List<QueryOrderLogisticsDetailVo.Detail> detailList = orderLogisticsService.queryOrderLogisticsDetail(orderId);
        vo.setDetailList(detailList);
        return ResponseResult.OK(vo);
    }

    /**
     * 根据公司名称查询订单
     * @param hotelName
     * @return
     */
    @GetMapping("/queryOrderByHotelName")
    public ResponseResult queryOrderByHotelName(String hotelName){
        return ordersService.queryOrderByHotelName(hotelName);
    }



    /**
     * 根据订单编号查询订单物流
     * @param orderId
     * @return
     */
    @GetMapping("/orderLogisticsList")
    public ResponseResult orderLogisticsList(@RequestParam String orderId){
        return orderLogisticsService.orderLogisticsList(orderId);
    }

    /**
     * 新增或修改物流单号
     * @param io
     * @return
     */
    @PostMapping("/saveOrUpdate")
    public ResponseResult saveOrUpdate(@RequestBody SaveOrUpdateIo io){
        io.setImage(io.getImage().replace(GlobalParam.IMAGE_URL, ""));
        LoginVo loginVo = GlobalParam.LOGIN_ACCOUNT_INFO.get();
        OrderLogistics orderLogistics;
        if (io.getId() > 0){
            orderLogistics = orderLogisticsService.getById(io.getId());
            orderLogistics.setLogisticName(io.getLogisticName()).setLogisticId(io.getLogisticId())
                    .setMobile(io.getMobile()).setComments(io.getComments()).setImage(io.getImage());
        }else{
            orderLogistics = new OrderLogistics().setOrderId(io.getOrderId()).setLogisticName(io.getLogisticName())
                    .setLogisticId(io.getLogisticId()).setComments(io.getComments()).setMobile(io.getMobile())
                    .setImage(io.getImage());
        }
        orderLogistics.setAccountId(loginVo.getId());
        boolean b = orderLogisticsService.saveOrUpdate(orderLogistics);
        if (b)
            ordersService.update(null, Wrappers.<Orders>lambdaUpdate().eq(Orders::getOrderId, io.getOrderId()).set(Orders::getStatus,  4));
        return ResponseResult.OK();
    }

    /**
     * 删除物流
     * @param id
     * @return
     */
    @GetMapping("/removeOrderLogistics")
    public ResponseResult  removeOrderLogistics(@RequestParam long id){
        boolean b = orderLogisticsService.removeById(id);
        if (b)
            return ResponseResult.OK();
        return  ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9999);
    }
}
